#!/bin/sh

#
# Test that the correct version of the redundant environment is always read
#
# This test runs fw_printenv if available to check that fwup's behavior matches.
#

. "$(cd "$(dirname "$0")" && pwd)/common.sh"

if [ $HOST_OS = "Windows" ]; then
    FW_PRINTENV=$(command -v fw_printenv || true)
fi

cat >$CONFIG <<EOF
define(UBOOT_ENV_OFFSET, 0)
define(UBOOT_ENV_COUNT, 2)
define(UBOOT_ENV_REDUND_OFFSET, 2)

uboot-environment uboot-env {
    block-offset = \${UBOOT_ENV_OFFSET}
    block-count = \${UBOOT_ENV_COUNT}
    block-offset-redund = \${UBOOT_ENV_REDUND_OFFSET}
}

# This firmware task writes everything to the destination media
task complete {
    on-init {
        uboot_clearenv(uboot-env)
        uboot_setenv(uboot-env, "counter", 2)
    }
}
EOF

i=0
while [ $i -le 257 ]; do
    next_i=$((i + 1))
    echo "task count.$next_i  { require-uboot-variable(uboot-env, \"counter\", $i)" >> $CONFIG
    echo "  on-finish { uboot_setenv(uboot-env, \"counter\", $next_i) }}" >> $CONFIG
    i=$next_i
done

cat >"$WORK/fw_env.config" <<EOF
$IMGFILE.copy 0x000 0x400
$IMGFILE.copy 0x400 0x400
EOF

# Create the expected result after being upgraded until the counter is 257.
#
# To recreate, run:
#
# Add an exit 1 at the end of the script, inspect the image to make sure it's right
# and then run "dd if=work-200_uboot_redundant_255.test/fwup.img count=4 | base64 -b 72 > out.base64"
#
# NOTE: To future self: don't be tempted by xxd. It would skip a line in
#       the output and that would leave a bunch of zeros and fail U-boot's CRC32.
base64_decode >$WORK/expected-env-257.img <<EOF
TlIUJAFjb3VudGVyPTI1NwAA////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////y1S
EUkAY291bnRlcj0yNTYAAP//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////8=
EOF

# Hand checked initial output. "counter=2" will be in the
base64_decode >$WORK/expected-env-2.img <<EOF
Q73LoQEA////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////149
XA4CY291bnRlcj0yAAD/////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////8=
EOF

# Create the firmware file, then "burn it"
$FWUP_CREATE -q -c -f $CONFIG -o $FWFILE
$FWUP_APPLY -q -a -d $IMGFILE -i $FWFILE -t complete

# Check the initial version to make sure that the initial ordering is the
# expected one. This does not matter except that it is easy to think about the
# even/odd-ness after 255 flops if this is done.
#
# The expectation is that the primary environment is the initialized empty
# environment and the secondary environment is the one with counter=2 in it.
# (Odd numbers in the primary slot, even ones in the redundant one)
dd if=$IMGFILE of=$WORK/actual-env.img count=4 2>/dev/null
cmp $WORK/expected-env-2.img $WORK/actual-env.img

check_fw_printenv() {
    if [ "$FW_PRINTENV" = "" ]; then
        return 0
    fi

    cp $IMGFILE $IMGFILE.copy
    fw_env=$($FW_PRINTENV -c "$WORK/fw_env.config")
    if [ "$fw_env" != "counter=$1" ]; then
        echo "fw_printenv didn't print expected"
        echo "     GOT: $fw_env"
        echo "EXPECTED: counter=$1"
        exit 1
    fi
 }

# Test that each update works:
#
# The apply specifies which count we are on. The require-uboot-variable check
# confirms that fwup is reading the right U-Boot environment. If it picks the
# wrong one, this will fail. As a second check, if `fw_printenv` is available,
# it's called to see if it reads the same value.
#
# The counter is initialized to 2 to match the U-Boot epoch counter for which
# environment to read. It should match mod 256 when inspecting the image.
i=3
while [ $i -le 257 ]; do
    echo "Updating counter to $i"
    $FWUP_APPLY -q -a -d $IMGFILE -i $FWFILE -t count.$i
    $FWUP_VERIFY -q -V -i $FWFILE

    check_fw_printenv $i
    i=$((i + 1))
done

# Compare the final version of the file to a hand checked version.
dd if=$IMGFILE of=$WORK/actual-env.img count=4 2>/dev/null
cmp $WORK/expected-env-257.img $WORK/actual-env.img

if [ "$FW_PRINTENV" = "" ]; then
    echo "WARNING: fw_printenv not found. Did not verify compatibility"
else
    echo "INFO: fw_printenv used to verify compatibility"
fi
